using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Admin.NET.Application.Entity;
using Admin.NET.Application.Entity.Business;
using Admin.NET.Application.Service.Mp.Dto;
using Admin.NET.Core;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace Admin.NET.Application.Service.Mp;

/// <summary>
/// 小程序首页服务
/// </summary>
[ApiDescriptionSettings(new string[] { "业务应用" }, Order = 100)]
public class MpHomeService : IDynamicApiController, ITransient, IPrivateDependency
{
	private readonly UserManager _userManager;

	private readonly SqlSugarRepository<Room> _rep;

	private readonly IHttpContextAccessor _httpContextAccessor;

	public MpHomeService(UserManager userManager, SqlSugarRepository<Room> rep, IHttpContextAccessor httpContextAccessor)
	{
		_userManager = userManager;
		_rep = rep;
		_httpContextAccessor = httpContextAccessor;
	}

	/// <summary>
	/// 业主获取所有房间
	/// </summary>
	/// <returns></returns>
	[HttpGet("/mp/homes")]
	public async Task<dynamic> GetHomes()
	{
		return await (from w in _rep.AsQueryable()
			where w.OwnerId == (long?)_userManager.UserId
			select w).ToListAsync();
	}

	/// <summary>
	/// 获取房间里的电表/或用户所有的电表
	/// </summary>
	/// <param name="roomId"></param>
	/// <returns></returns>
	[HttpGet("/mp/meters")]
	public async Task<dynamic> GetMeters([FromQuery] long? roomId)
	{
		var allroom = await (from w in _rep.AsQueryable()
			where w.OwnerId == (long?)_userManager.UserId
			select new { w.Id, w.Name }).ToListAsync();
		ISugarQueryable<ElectricMeter> query = _rep.Context.Queryable<ElectricMeter>();
		if (roomId.HasValue)
		{
			if (!allroom.Any(a => a.Id == roomId))
			{
				throw Oops.Bah("无权限");
			}
			query = query.Where((ElectricMeter w) => roomId == w.RoomId);
		}
		else
		{
			List<long> roomIds = allroom.Select(s => s.Id).ToList();
			query = query.Where((ElectricMeter w) => roomIds.Contains((long)w.RoomId));
		}
		List<RoomMeterDto> result = await (from w in query
			orderby w.CreateTime
			select new RoomMeterDto
			{
				Id = w.Id,
				Name = w.Name,
				Sn = w.Sn,
				GateStatus = w.GateStatus,
				SignalStatus = w.SignalStatus,
				CreateTime = w.CreateTime,
				RoomId = w.RoomId,
				BuildingId = w.BuildingId,
				PriceRuleId = w.PriceRuleId,
				OwnerControl = w.OwnerControl,
				CombinedActiveTotalElectricEnergy = w.CombinedActiveTotalElectricEnergy,
				BuildingName = from b in SqlFunc.Subqueryable<Building>()
					where (long?)b.Id == w.BuildingId
					select b.Name
			}).ToListAsync();
		List<long?> ruleIds = (from u in result
			where u.PriceRuleId.HasValue
			select u.PriceRuleId).ToList();
		List<ElectricityPriceRule> allRules = await (from u in _rep.Context.Queryable<ElectricityPriceRule>()
			where ruleIds.Contains(u.Id)
			select u).ToListAsync();
		foreach (RoomMeterDto item in result)
		{
			item.RoomName = (from w in allroom
				where w.Id == item.RoomId
				select w into s
				select s.Name).FirstOrDefault();
			if (!item.CombinedActiveTotalElectricEnergy.HasValue)
			{
				item.CombinedActiveTotalElectricEnergy = default(decimal);
			}
			else
			{
				item.CombinedActiveTotalElectricEnergy = Math.Round(item.CombinedActiveTotalElectricEnergy.Value, 2);
			}
			if (item.PriceRuleId.HasValue)
			{
				item.ElectricityPriceRule = allRules.Where((ElectricityPriceRule u) => u.Id == item.PriceRuleId).FirstOrDefault();
			}
		}
		return result;
	}

	/// <summary>
	/// 获取房间详情
	/// </summary>
	/// <param name="roomId"></param>
	/// <returns></returns>
	[HttpGet("/mp/homeinfo")]
	public async Task<dynamic> GetHomeInfo(long roomId)
	{
		return await (from s in _rep.AsQueryable()
			where s.Id == roomId
			select new RoomInfoOutput
			{
				Id = s.Id,
				Name = s.Name,
				Area = s.Area,
				Balance = s.Balance,
				BuildingId = s.BuildingId,
				TenantId = s.TenantId,
				CreateTime = s.CreateTime,
				CreateUserId = s.CreateUserId,
				IsDelete = s.IsDelete,
				LatestWarningBalance = s.LatestWarningBalance,
				OwnerId = s.OwnerId,
				Remark = s.Remark,
				UpdateTime = s.UpdateTime,
				UpdateUserId = s.UpdateUserId,
				WarningRuleId = s.WarningRuleId,
				BuildingName = from b in SqlFunc.Subqueryable<Building>()
					where b.Id == s.BuildingId
					select b.Name
			}).FirstAsync();
	}

	/// <summary>
	/// 获取通知
	/// </summary>
	/// <param name="page"></param>
	/// <param name="limit"></param>
	/// <param name="query"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	[HttpGet("/mp/notice")]
	public async Task<dynamic> GetNotices(int page, int limit, string query, NoticeTypeEnum? type)
	{
		return await (from w in (from w in _rep.Context.Queryable<SysNotice>()
				where (int)w.Status == 1 && !string.IsNullOrWhiteSpace(w.Img)
				select w).WhereIF(type.HasValue, (SysNotice w) => (int?)w.Type == (int?)type).WhereIF(!string.IsNullOrWhiteSpace(query), (SysNotice w) => w.Title.Contains(query.Trim()) || w.Content.Contains(query.Trim()))
			orderby w.PublicTime descending
			select w into s
			select new SysNotice
			{
				Id = s.Id,
				Title = s.Title,
				Img = s.Img,
				PublicUserName = s.PublicUserName
			}).ToPagedListAsync(page, limit);
	}

	/// <summary>
	/// 获取通知
	/// </summary>
	/// <param name="page"></param>
	/// <param name="limit"></param>
	/// <param name="query"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	[HttpGet("/mp/noticev2")]
	public async Task<dynamic> GetNoticesV2(int page, int limit, string query, NoticeTypeEnum? type)
	{
		return await (from w in (from w in _rep.Context.Queryable<SysNotice>()
				where (int)w.Status == 1
				select w).WhereIF(type.HasValue, (SysNotice w) => (int?)w.Type == (int?)type).WhereIF(!string.IsNullOrWhiteSpace(query), (SysNotice w) => w.Title.Contains(query.Trim()) || w.Content.Contains(query.Trim()))
			orderby w.PublicTime descending
			select w).ToPagedListAsync(page, limit);
	}

	/// <summary>
	/// 获取通知详细内容
	/// </summary>
	/// <param name="id"></param>
	/// <returns></returns>
	[HttpGet("/mp/noticeDetail")]
	public async Task<dynamic> GetNoticeDetail(long id)
	{
		return await _rep.Context.Queryable<SysNotice>().FirstAsync((SysNotice f) => f.Id == id);
	}

	/// <summary>
	/// 获取logo
	/// </summary>
	/// <returns></returns>
	[HttpGet("/mp/getlogo")]
	public async Task<dynamic> GetLogo()
	{
		return await (from w in _rep.Context.Queryable<SysUser>()
			where w.TenantId == (long?)_userManager.TenantId && (int)w.AccountType == 888
			select w.Avatar).FirstAsync();
	}

	/// <summary>
	/// 获取需要关注的信息，即将欠费，待充值，具有待支付的账单
	/// </summary>
	/// <returns></returns>
	[HttpGet("/mp/getneedattention")]
	public async Task<dynamic> GetNeedAttention()
	{
		return new
		{
			roomWarningCount = await (from u in _rep.Context.Queryable<Room>()
				where u.OwnerId == (long?)_userManager.UserId && u.Balance < 50m && u.WarningRuleId > (long?)0L
				select u).CountAsync(),
			customBillCount = await (from u in _rep.Context.Queryable<CustomRoomBill>()
				where u.OwnerId == (long?)_userManager.UserId && u.Status == 1
				select u).CountAsync()
		};
	}
}
